package com.example.demo.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.Bean.*;
import com.example.demo.Mapper.*;
import com.example.demo.Utils.SqlUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


@Service
public class StudentService {

    @Autowired
    StudentMapper studentMapper;
    @Autowired
    StudentClassMapper studentClassMapper;
    @Autowired
    TeacherClassMapper teacherClassMapper;
    @Autowired
    ExperimentStuService experimentStuService;
    @Autowired
    ReportService reportService;
    @Autowired
    TeamMapper teamMapper;
    @Autowired
    BelongMapper belongMapper;
    @Autowired
    SqlUtil sqlUtil;
    @Autowired
    ReportMapper reportMapper;


    public Result getAllStudent(String courseId) throws Exception{
        Result result = null;
            List<String> s_ids = new ArrayList<>();
            List<StudentClass> studentClasses = studentClassMapper.selectList(new QueryWrapper<StudentClass>().eq("course_id",courseId));
            for (int n = 0 ; n < studentClasses.size() ; n++){
                s_ids.add(studentClasses.get(n).getStudentUid());
            }
            List<Student> students = studentMapper.selectBatchIds(s_ids);
            result = new Result(200,students);
        return result;
    }


    public Result getStudentDetail(String student_uid) throws Exception{
        Result result = null;
            Student student = studentMapper.selectById(student_uid);
            if (student != null) {
                result = new Result(200, student);
            } else {
                result = new Result(403, "获取失败！");
            }
        return result;
    }


    public Result modifyStudentDetail(String studentUid,String studentName,String classees,String email) throws Exception{
        Result result = null;
            Student student = new Student();
            java.util.Date updateTime = new Date();
            student.setStudentUid(studentUid);
            student.setName(studentName);
            student.setClasses(classees);
            student.setEmail(email);
            student.setUpdateTime(updateTime);
            Integer r = studentMapper.updateById(student);
            if (r >= 1) {
                result = new Result(200, "修改成功");
            } else {
                result = new Result(403, "修改失败！");
            }
        return result;
    }


    public Result modifyStudentPassword(String studentUid,String password) throws Exception{
        Result result = null;
            Student student = new Student();
            Date updateTime = new Date();
            student.setStudentUid(studentUid);
            student.setPassword(password);
            student.setUpdateTime(updateTime);
            Integer r = studentMapper.updateById(student);
            if (r >= 1) {
                result = new Result(200, "修改成功");
            } else {
                result = new Result(403, "修改失败！");
            }
        return result;
    }


    public Result addStudent(String studentUid,String password,String classes,String name,String courseId) throws Exception{
        Result result = null;
            Student stu=studentMapper.selectOne(new QueryWrapper<Student>().eq("student_uid",studentUid));
            if(stu!=null){
                result = new Result(403,"该学号已存在于某一班级!");
                return result;
            }
            Student student = new Student();
            Date updateTime = new Date();
            Date createTime = new Date();
            student.setStudentUid(studentUid);
            student.setPassword(password);
            student.setUpdateTime(updateTime);
            student.setCreateTime(createTime);
            student.setClasses(classes);
            student.setName(name);
            Integer r = studentMapper.insert(student);
            if (r >= 1) {
                result = new Result(200, "添加成功！");
                StudentClass studentClass = new StudentClass();
                studentClass.setStudentUid(studentUid);
                studentClass.setCourseId(courseId);
                studentClassMapper.insert(studentClass);
            } else {
                result = new Result(403, "操作失败！");
            }
        return result;
    }

    public void saveList(List<Student> list,String courseId) throws Exception {
        List<Student> lists = new ArrayList<>();
        int n = 0,m = 0;
            for (Student s : list){
                s.setPassword(s.getStudentUid());
                s.setCreateTime(new Date());
                s.setUpdateTime(new Date());
                n++;
                if (n > 1){
                    lists.add(s);
                }
            }
        studentMapper.saveAll(lists);
        StudentClass studentClass = new StudentClass();
        studentClass.setCourseId(courseId);
            for (Student stu : list){
                m++;
                if (m > 1){
                    String s = stu.getStudentUid();
                    studentClass.setStudentUid(s);
                    studentClassMapper.insert(studentClass);
                }
            }
    }


    public Result searchStudent(String name,String courseId,Integer pageNum,Integer pageSize) throws Exception{
        Result result = null;
            List<StudentClass> studentClasses = studentClassMapper.selectList(new QueryWrapper<StudentClass>().eq("course_id",courseId));
            Map<String,Object> res = new HashMap<>();
            List<String> s_ids = new ArrayList<>();
            for (StudentClass studentClass : studentClasses) {
                s_ids.add(studentClass.getStudentUid());
            }
            if(s_ids.size() == 0){
                s_ids.add("-1");
            }
            Page<Student> page = new Page<>(pageNum,pageSize);
            page = studentMapper.selectPage(page,new QueryWrapper<Student>().like("name",name).and(wrapper -> {wrapper.in("student_uid",s_ids);}));
            Integer total = studentMapper.selectList(new QueryWrapper<Student>().like("name",name).and(wrapper -> {wrapper.in("student_uid",s_ids);})).size();
            if(page.getRecords().size() == 0){
                page = studentMapper.selectPage(page,new QueryWrapper<Student>().like("student_uid",name).and(wrapper -> {wrapper.in("student_uid",s_ids);}));
                total = studentMapper.selectList(new QueryWrapper<Student>().like("student_uid",name).and(wrapper -> {wrapper.in("student_uid",s_ids);})).size();
            }
            List<Student> list = page.getRecords();
            res.put("page",pageNum);
            res.put("size",pageSize);
            res.put("total",total);
            res.put("totalPage",total%pageSize>=1 ? total/pageSize+1 : total/pageSize);
            if (list.size() == 0) {
                res.put("list",list);
                result = new Result(200, res);
                return result;
            }
            List<Experiment> experimentList = experimentStuService.getExperimentList(courseId);
            List<String> studentUids = new ArrayList<>();
            for (Student student : list) {
                studentUids.add(student.getStudentUid());
            }
            List<Report> reportList = reportService.getList(studentUids);
            Map<Integer,Experiment> experimentMap = new HashMap<>();
            for (Experiment experiment : experimentList) {
                experimentMap.put(experiment.getExperimentId(),experiment);
            }
            for (Report report : reportList) {
                for (Student student : list) {
                    if(report.getStudentUid().equals(student.getStudentUid())){
                        student.setTotalScore(student.getTotalScore() + experimentMap.get(report.getExperimentId()).getScale() / 100 * report.getCode());
                    }
                }
            }
            res.put("list",list);
            result = new Result(200,res);
        return result;
    }


    public Result deleteStudent(String student_uid,String courseId) throws Exception{
        Result result = null;
            Integer r = studentMapper.deleteById(student_uid);
            if (r >= 1) {
                result = new Result(200, "删除成功！");
                HashMap map = new HashMap<>();
                map.put("student_uid",student_uid);
                map.put("course_id",courseId);
                studentClassMapper.deleteByMap(map);
                sqlUtil.deleteUserPlace(student_uid);
            } else {
                result = new Result(403, "操作失败！");
            }
        return result;
    }


    public Result getStudentPage(Integer pageNum,Integer pageSize,String courseId) throws Exception{
        Result result = null;
            Map<String,Object> res = new HashMap<>();
            res.put("page",pageNum);
            res.put("size",pageSize);
            Integer total = (Integer)getTotalStudentNum(courseId).getObj();
            res.put("total",total);
            res.put("totalPage",total%pageSize>=1 ? total/pageSize+1 : total/pageSize);
            List<StudentClass> studentClasses = studentClassMapper.selectList(new QueryWrapper<StudentClass>().eq("course_id",courseId));
            List<String> s_ids = new ArrayList<>();
            for (StudentClass studentClass : studentClasses) {
                s_ids.add(studentClass.getStudentUid());
            }
            Page<Student> page = new Page<>(pageNum, pageSize);
            page = studentMapper.selectPage(page,new QueryWrapper<Student>().in("student_uid",s_ids));
            res.put("list",page.getRecords());
            result = new Result(200, res);
        return result;
    }


    public Result getTotalStudentNum(String courseId) throws Exception{
        Result result = null;
            List<Student> students = studentMapper.selectList(null);
            HashMap map = new HashMap();
            map.put("course_id", courseId);
            Iterator<Student> iterator = students.iterator();
            while (iterator.hasNext()) {
                Student next = iterator.next();
                map.put("student_uid", next.getStudentUid());
                StudentClass st = studentClassMapper.selectOne(new QueryWrapper<>().allEq(map));
                if(st==null){
                    iterator.remove();
                }
            }
            result = new Result(200, students.size());
        return result;
    }

    public Result getAll(String courseId) throws Exception{
        List<String> s_ids = new ArrayList<>();
        List<StudentClass> studentClasses = studentClassMapper.selectList(new QueryWrapper<StudentClass>().eq("course_id", courseId));
        for (int n = 0; n < studentClasses.size(); n++) {
            s_ids.add(studentClasses.get(n).getStudentUid());
        }
        List<Student> students = studentMapper.selectBatchIds(s_ids);
        return new Result(200,students);
    }

    public Result createGroup(List<String> ids, String groupName, String courseId) throws Exception{
            Team team = new Team(courseId,groupName);
            teamMapper.insert(team);
            for (String id : ids) {
                belongMapper.insert(new Belong(id, team.getGroupId()));
            }
            return new Result(200, "添加组成功！");
    }

    public Result modifyGroupName(Integer groupId, String groupName) throws Exception{
            teamMapper.update(null, new UpdateWrapper<Team>().eq("group_id",groupId).set("name",groupName));
            return new Result(200,"修改成功！");
    }

    public Result getGroup(String courseId) throws Exception{
            List<Team> groups = teamMapper.selectList(new QueryWrapper<Team>().eq("course_id", courseId));
            return new Result(200,groups);
    }

    public Result getGroupMember(Integer groupId) throws Exception{
            List<Belong> belongs = belongMapper.selectList(new QueryWrapper<Belong>().eq("group_id", groupId));
            List<String> ids = new ArrayList<>();
            for (Belong belong : belongs) {
                ids.add(belong.getStudentUid());
            }
            List<Student> students = new ArrayList<>();
            if(ids.size() == 0){
                return new Result(200,"组内无成员");
            }
            students = studentMapper.selectBatchIds(ids);
            return new Result(200,students);
    }

    public Result deleteGroup(Integer groupId) throws Exception{
            belongMapper.delete(new QueryWrapper<Belong>().eq("group_id", groupId));
            teamMapper.deleteById(groupId);
            return new Result(200,"已删除");
    }

    public Result deleteGroupMember(List<String> ids, Integer groupId) throws Exception{
            List<Belong> belongs = belongMapper.selectList(new QueryWrapper<Belong>().eq("group_id", groupId));
            List<String> currentIds = new ArrayList<>();
            for (Belong belong : belongs) {
                currentIds.add(belong.getStudentUid());
            }
            for (String id : ids) {
                if(currentIds.contains(id)){
                    belongMapper.delete(new QueryWrapper<Belong>().eq("student_uid",id).eq("group_id",groupId));
                }
            }
            return new Result(200, "删除成功！");
    }

    public Result createGroupMember(List<String> ids, Integer groupId) throws Exception{
            List<Belong> belongs = belongMapper.selectList(new QueryWrapper<Belong>().eq("group_id", groupId));
            List<String> currentIds = new ArrayList<>();
            for (Belong belong : belongs) {
                currentIds.add(belong.getStudentUid());
            }
            for (String id : ids) {
                if(!currentIds.contains(id)){
                    belongMapper.insert(new Belong(id, groupId));
                }
            }
            return new Result(200, "添加成功！");
    }

    public Result totalScore(String courseId, List<ScoreBean> scoreBeans) throws Exception{
        List<StudentClass> studentClasses = studentClassMapper.selectList(new QueryWrapper<StudentClass>().eq("course_id",courseId));
        List<String> studentIds = studentClasses.stream().map(StudentClass::getStudentUid).collect(Collectors.toList());
        List<Student> students = studentMapper.selectBatchIds(studentIds);
        float temp = 0.0f;
        Map<Student,Float> scores = new HashMap<>();
        for (Student student : students) {
            for (ScoreBean scoreBean : scoreBeans) {
                Report report = reportMapper.selectOne(new QueryWrapper<Report>().eq("student_uid",student.getStudentUid()).eq("experiment_id",scoreBean.getExperimentId()));
                if(report != null){
                    temp += report.getCode() * (scoreBean.getPercentAge() / 100.0);
                }

            }
            scores.put(student, temp);
            temp = 0.0f;
        }
        return new Result(200,scores);
    }

}
